package facade

import "fmt"

func NewAPI() API {
	return &apiImpl{
		a: NewAModuleAPI(),
		b: NewBModuleAPI(),
	}
}

//API is facade interface of facade package
type API interface {
	Test() string
}

//facade implement 外观角色
type apiImpl struct {
	a AModuleAPI
	b BModuleAPI
}

// 向客户端提供了一个客户端可以访问系统的接口的实现
// 客户端无须自己去组装各个子系统的接口调用
// 例如：这里Test就是组装一台汽车，TestA/TestB是组装汽车里面的零部件
func (a *apiImpl) Test() string {
	aRet := a.a.TestA()
	bRet := a.b.TestB()
	return fmt.Sprintf("%s\n%s", aRet, bRet)
}

//NewAModuleAPI return new AModuleAPI
func NewAModuleAPI() AModuleAPI {
	return &aModuleImpl{}
}

//AModuleAPI ...
type AModuleAPI interface {
	TestA() string
}

// 子系统角色A
type aModuleImpl struct{}

func (*aModuleImpl) TestA() string {
	return "A module running"
}

//NewBModuleAPI return new BModuleAPI
func NewBModuleAPI() BModuleAPI {
	return &bModuleImpl{}
}

//BModuleAPI ...
type BModuleAPI interface {
	TestB() string
}

// 子系统角色B
type bModuleImpl struct{}

func (*bModuleImpl) TestB() string {
	return "B module running"
}
